import pygame
import random
import sys
import time
import os
import math # Added for sin function

# 导入菜单模块
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from 菜单.init_menu import draw_menu, handle_menu_click, draw_exit_confirm_dialog, draw_rules_screen, draw_game_menu, draw_game_exit_confirm_dialog

# 导入模型模块
from 模型.model import (
    draw_snake, draw_food, draw_items, draw_obstacles, 
    draw_game_background, draw_info_panel, draw_start_screen, draw_pause_screen,
    get_theme_colors, THEMES, BLACK, GREEN, RED, WHITE, GRID_COLOR, LIGHT_GRAY, 
    LIGHT_BLUE, YELLOW, DARK_GREEN, GOLD, PURPLE, CYAN, ORANGE, PINK, BLUE, 
    DARK_BLUE, DARK_RED, DARK_PURPLE, DARK_CYAN
)

pygame.init()
try:
    pygame.mixer.init()  # 初始化声音系统
    mixer_available = True
except Exception as e:
    print(f"声音系统初始化失败: {e}")
    mixer_available = False

# 设置窗口图标和标题
pygame.display.set_caption("贪吃蛇（不会死亡）")

# 获取系统可用字体
available_fonts = pygame.font.get_fonts()
chinese_fonts = ["simhei", "simsun", "microsoftyahei", "kaiti", "heiti"]
selected_font = None
for font in chinese_fonts:
    if font in available_fonts:
        selected_font = font
        break

# 颜色常量已从model模块导入

# 主题设置已从model模块导入

# 当前主题
current_theme = "经典"
theme_colors = get_theme_colors(current_theme)

# 设置地图和窗口尺寸
MAP_WIDTH, MAP_HEIGHT = 600, 600
INFO_WIDTH = 260
WIDTH, HEIGHT = MAP_WIDTH + INFO_WIDTH, MAP_HEIGHT
CELL_SIZE = 20
GRID_WIDTH = MAP_WIDTH // CELL_SIZE
GRID_HEIGHT = MAP_HEIGHT // CELL_SIZE
screen = pygame.display.set_mode((WIDTH, HEIGHT))

# 初始化游戏元素
snake = [
    [5, 5],  # 存储网格坐标，而非像素坐标
    [4, 5],
    [3, 5]
]
snake_pixels = []  # 存储每个蛇身体部分的像素坐标
direction = (1, 0)
food = [random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1)]
food_type = 0  # 0 = 普通食物, 1 = 特殊食物(+2分), 2 = 超级食物(+3分)
food_timer = 0  # 特殊食物计时器
score = 0
snake_length = 3
smooth_animation = True  # 是否启用平滑动画
game_started = False  # 游戏是否已开始
animation_progress = 0.0  # 动画进度，从0到1

# 初始化障碍物和道具
obstacles = []  # 障碍物位置列表
obstacle_count = 0  # 当前障碍物数量
max_obstacles = 8  # 最大障碍物数量
obstacle_timer = 0  # 障碍物生成计时器
obstacle_interval = 15000  # 每15秒生成一个障碍物

# 道具系统
items = []  # 道具位置和类型 [x, y, type]
item_types = ["speed", "slow", "double", "clear"]  # 加速,减速,双倍分数,清除障碍
item_timer = 0  # 道具生成计时器
item_interval = 20000  # 每20秒生成一个道具
active_effects = {}  # 激活的效果 {"effect_name": end_time}

# 初始化像素坐标
for segment in snake:
    snake_pixels.append([segment[0] * CELL_SIZE, segment[1] * CELL_SIZE])

# 记录按键队列，防止快速按键时丢失输入
key_queue = []

# 尝试加载声音文件
try:
    eat_sound = pygame.mixer.Sound(os.path.join("game", "贪吃蛇_不会死亡", "eat.wav"))
    eat_sound.set_volume(0.5)
    special_eat_sound = pygame.mixer.Sound(os.path.join("game", "贪吃蛇_不会死亡", "special_eat.wav"))
    special_eat_sound.set_volume(0.6)
    move_sound = pygame.mixer.Sound(os.path.join("game", "贪吃蛇_不会死亡", "move.wav"))
    move_sound.set_volume(0.2)
    start_sound = pygame.mixer.Sound(os.path.join("game", "贪吃蛇_不会死亡", "start.wav"))
    start_sound.set_volume(0.7)
    item_sound = pygame.mixer.Sound(os.path.join("game", "贪吃蛇_不会死亡", "item.wav"))
    item_sound.set_volume(0.7)
    sounds_loaded = True
except:
    sounds_loaded = False
    print("无法加载声音文件")

# 游戏状态
clock = pygame.time.Clock()
FPS = 60  # 帧率
speed = 6  # 每秒移动的格子数
paused = False
start_time = time.time()
pause_start_time = None  # 记录暂停开始时刻
total_pause_time = 0     # 累计暂停时长
last_elapsed_time = 0    # 暂停时的显示缓存

# 移动控制
move_timer = 0
move_delay = 1000 / speed  # 毫秒
next_direction = direction  # 记录下一个方向

# 菜单状态
game_state = "menu"  # "menu", "game", "rules", "exit_confirm", "game_menu", "game_exit_confirm"
menu_buttons = []
showing_rules = False
showing_exit_confirm = False
scroll_offset = 0
content_height = 0
content_area_height = 0
dragging_scrollbar = False
from_game_menu = False  # 标记是否从游戏内菜单进入规则界面

# 初始化菜单按钮
menu_buttons = draw_menu(screen, WIDTH, HEIGHT)

# 创建字体（使用系统字体确保中文显示正常）
if selected_font:
    main_font = pygame.font.SysFont(selected_font, 36)
    info_font = pygame.font.SysFont(selected_font, 24)
    small_font = pygame.font.SysFont(selected_font, 18)
    tiny_font = pygame.font.SysFont(selected_font, 16)  # 添加更小的字体用于操作说明
else:
    main_font = pygame.font.SysFont(pygame.font.get_default_font(), 36)
    info_font = pygame.font.SysFont(pygame.font.get_default_font(), 24)
    small_font = pygame.font.SysFont(pygame.font.get_default_font(), 18)
    tiny_font = pygame.font.SysFont(pygame.font.get_default_font(), 16)  # 添加更小的字体用于操作说明


def draw():
    global last_elapsed_time, menu_buttons, content_height, content_area_height
    
    # 根据游戏状态绘制不同界面
    if game_state == "menu":
        # 绘制菜单界面
        menu_buttons = draw_menu(screen, WIDTH, HEIGHT)
        return menu_buttons
    elif game_state == "rules":
        # 绘制规则界面
        back_button, content_height, content_area_height = draw_rules_screen(screen, WIDTH, HEIGHT, scroll_offset)
        return back_button, content_height, content_area_height
    elif game_state == "exit_confirm":
        # 绘制退出确认界面
        yes_button, no_button = draw_exit_confirm_dialog(screen, WIDTH, HEIGHT)
        return yes_button, no_button
    elif game_state == "game_menu":
        # 绘制游戏内菜单弹窗
        continue_button, rules_button, exit_button = draw_game_menu(screen, WIDTH, HEIGHT)
        return continue_button, rules_button, exit_button
    elif game_state == "game_exit_confirm":
        # 绘制游戏内退出确认对话框
        yes_button, no_button = draw_game_exit_confirm_dialog(screen, WIDTH, HEIGHT)
        return yes_button, no_button
    elif game_state == "game":
        # 绘制游戏界面
        draw_game()
    
def draw_game():
    global last_elapsed_time
    # 绘制背景和网格线
    draw_game_background(screen, theme_colors, MAP_WIDTH, MAP_HEIGHT, CELL_SIZE)

    if not game_started:
        # 显示开始界面
        draw_start_screen(screen, MAP_WIDTH, MAP_HEIGHT, selected_font, GREEN, WHITE, LIGHT_BLUE)
        
        # 显示当前主题
        current_theme_text = info_font.render(f"当前主题: {current_theme}", True, WHITE)
        screen.blit(current_theme_text, (MAP_WIDTH // 2 - current_theme_text.get_width() // 2, MAP_HEIGHT // 2 + 90))
    else:
        # 绘制障碍物
        draw_obstacles(screen, obstacles, theme_colors, CELL_SIZE)
        
        # 绘制道具
        draw_items(screen, items, CELL_SIZE, small_font)
        
        # 绘制蛇
        draw_snake(screen, snake, snake_pixels, direction, theme_colors, smooth_animation, active_effects, CELL_SIZE)
        
        # 绘制食物
        draw_food(screen, food, food_type, theme_colors, CELL_SIZE)

    # 绘制信息面板
    if not game_started:
        elapsed_time = 0
    elif paused:
        elapsed_time = last_elapsed_time
    else:
        elapsed_time = time.time() - start_time - total_pause_time
        last_elapsed_time = elapsed_time
    
    draw_info_panel(screen, theme_colors, MAP_WIDTH, INFO_WIDTH, HEIGHT, score, elapsed_time, speed, 
                   obstacle_count, max_obstacles, current_theme, smooth_animation, active_effects, 
                   main_font, info_font, small_font, LIGHT_BLUE, WHITE, GREEN, RED, ORANGE, CYAN, GOLD)

    # 如果暂停，显示暂停信息
    if game_started and paused:
        draw_pause_screen(screen, MAP_WIDTH, MAP_HEIGHT, main_font, info_font, RED, WHITE)


def move_snake():
    global food, score, direction, snake_length, next_direction, move_delay, speed, food_type, food_timer
    if paused or not game_started:
        return

    # 播放移动音效
    if sounds_loaded and random.random() < 0.1:  # 随机播放，避免太吵
        pygame.mixer.Sound.play(move_sound)
    
    # 处理输入队列中的方向变化
    if key_queue:
        next_direction = key_queue.pop(0)

    # 应用方向变化
    direction = next_direction
    
    # 获取蛇头位置
    head_x, head_y = snake[0]
    
    # 计算新头部位置
    new_x = head_x + direction[0]
    new_y = head_y + direction[1]

    # 穿墙处理
    new_x %= GRID_WIDTH
    new_y %= GRID_HEIGHT

    # 添加新头部
    snake.insert(0, [new_x, new_y])
    
    # 更新像素坐标数组
    new_head_pixel = [new_x * CELL_SIZE, new_y * CELL_SIZE]
    snake_pixels.insert(0, new_head_pixel)
    
    # 检查是否碰到障碍物
    if [new_x, new_y] in obstacles:
        # 不会死亡，但会失去一些分数和长度
        penalty = min(3, score // 5 + 1)  # 根据当前分数计算惩罚
        score = max(0, score - penalty)
        snake_length = max(3, snake_length - penalty)  # 最少保留3个长度
        
        # 删除障碍物
        obstacles.remove([new_x, new_y])
        global obstacle_count
        obstacle_count -= 1
        
    # 检查是否吃到道具
    item_eaten = None
    for item in items:
        if [new_x, new_y] == item[:2]:  # 比较坐标
            item_eaten = item
            break
    
    if item_eaten:
        items.remove(item_eaten)
        apply_item_effect(item_eaten[2])  # 应用道具效果
    
    # 检查是否吃到食物
    if snake[0] == food:
        # 根据食物类型增加分数
        points = 1
        if food_type == 1:
            points = 2
        elif food_type == 2:
            points = 3
        
        # 如果有双倍分数效果，翻倍得分
        if "double" in active_effects:
            points *= 2
        
        score += points
        snake_length += points
        
        # 播放音效
        if sounds_loaded:
            if food_type > 0:
                pygame.mixer.Sound.play(special_eat_sound)
            else:
                pygame.mixer.Sound.play(eat_sound)
        
        # 生成新食物，确保不在蛇身上
        generate_new_food()
    else:
        # 如果没有吃到食物，移除尾部
        if len(snake) > snake_length:
            snake.pop()
            if len(snake_pixels) > snake_length:
                snake_pixels.pop()
    
    # 处理特殊食物计时器
    if food_type > 0:
        food_timer -= 1
        if food_timer <= 0:
            # 特殊食物超时，重新生成普通食物
            food_type = 0
            generate_new_food()


def generate_new_food():
    global food, food_type, food_timer
    
    # 计算有效位置（排除蛇和障碍物）
    valid_positions = []
    for x in range(GRID_WIDTH):
        for y in range(GRID_HEIGHT):
            pos = [x, y]
            if pos not in snake and pos not in obstacles and not any(pos == item[:2] for item in items):
                valid_positions.append(pos)
    
    # 如果没有有效位置，返回
    if not valid_positions:
        return
    
    # 随机选择一个有效位置
    food = random.choice(valid_positions)
    
    # 随机生成特殊食物
    food_chance = random.random()
    if food_chance < 0.05:  # 5%的几率出现超级食物
        food_type = 2
        food_timer = int(7 * FPS)  # 超级食物存在7秒
    elif food_chance < 0.2:  # 15%的几率出现特殊食物
        food_type = 1
        food_timer = int(10 * FPS)  # 特殊食物存在10秒
    else:
        food_type = 0  # 普通食物不会消失


def generate_obstacle():
    global obstacles, obstacle_count
    
    # 如果已经达到最大障碍物数量，返回
    if obstacle_count >= max_obstacles:
        return
    
    # 计算有效位置（排除蛇、食物和现有障碍物）
    valid_positions = []
    for x in range(GRID_WIDTH):
        for y in range(GRID_HEIGHT):
            pos = [x, y]
            if pos not in snake and pos != food and pos not in obstacles and not any(pos == item[:2] for item in items):
                # 确保障碍物不会生成在蛇头周围
                if abs(pos[0] - snake[0][0]) > 2 or abs(pos[1] - snake[0][1]) > 2:
                    valid_positions.append(pos)
    
    # 如果没有有效位置，返回
    if not valid_positions:
        return
    
    # 随机选择一个有效位置
    obstacle = random.choice(valid_positions)
    obstacles.append(obstacle)
    obstacle_count += 1


def generate_item():
    global items
    
    # 最多同时存在2个道具
    if len(items) >= 2:
        return
    
    # 计算有效位置（排除蛇、食物、障碍物和现有道具）
    valid_positions = []
    for x in range(GRID_WIDTH):
        for y in range(GRID_HEIGHT):
            pos = [x, y]
            if pos not in snake and pos != food and pos not in obstacles and not any(pos == item[:2] for item in items):
                valid_positions.append(pos)
    
    # 如果没有有效位置，返回
    if not valid_positions:
        return
    
    # 随机选择一个有效位置和道具类型
    item_pos = random.choice(valid_positions)
    item_type = random.choice(item_types)
    
    # 添加新道具
    items.append([item_pos[0], item_pos[1], item_type])


def apply_item_effect(item_type):
    global speed, move_delay, active_effects, obstacles, obstacle_count
    
    current_time = pygame.time.get_ticks()
    
    # 播放道具音效
    if sounds_loaded:
        pygame.mixer.Sound.play(item_sound)
    
    # 根据道具类型应用效果
    if item_type == "speed":
        # 加速效果
        original_speed = speed
        speed = min(20, speed + 4)  # 增加速度，最高20
        move_delay = 1000 / speed
        
        # 添加到活动效果
        active_effects["speed"] = current_time + 10000  # 10秒
        
        # 如果有减速效果，移除
        if "slow" in active_effects:
            del active_effects["slow"]
    
    elif item_type == "slow":
        # 减速效果
        original_speed = speed
        speed = max(2, speed - 2)  # 减少速度，最低2
        move_delay = 1000 / speed
        
        # 添加到活动效果
        active_effects["slow"] = current_time + 10000  # 10秒
        
        # 如果有加速效果，移除
        if "speed" in active_effects:
            del active_effects["speed"]
    
    elif item_type == "double":
        # 双倍分数效果
        active_effects["double"] = current_time + 15000  # 15秒
    
    elif item_type == "clear":
        # 清除所有障碍物
        obstacles = []
        obstacle_count = 0


def update_snake_pixels(dt):
    """更新蛇的像素位置，实现平滑动画"""
    global animation_progress
    
    if not smooth_animation or paused or not game_started:
        return
        
    # 计算每帧移动的像素数
    pixels_per_frame = (CELL_SIZE * speed) / FPS
    
    # 更新每个蛇身部分的像素位置
    for i in range(len(snake_pixels)):
        if i < len(snake):  # 确保索引有效
            target_x = snake[i][0] * CELL_SIZE
            target_y = snake[i][1] * CELL_SIZE
            
            # 如果像素位置与目标位置不同，进行平滑移动
            if snake_pixels[i][0] != target_x or snake_pixels[i][1] != target_y:
                # 计算方向向量
                dx = target_x - snake_pixels[i][0]
                dy = target_y - snake_pixels[i][1]
                
                # 穿墙处理（当距离过大时）
                if abs(dx) > MAP_WIDTH / 2:
                    dx = -math.copysign(MAP_WIDTH - abs(dx), dx)
                if abs(dy) > MAP_HEIGHT / 2:
                    dy = -math.copysign(MAP_HEIGHT - abs(dy), dy)
                
                # 计算移动距离
                distance = math.sqrt(dx*dx + dy*dy)
                
                # 如果距离很小，直接设置为目标位置
                if distance < pixels_per_frame:
                    snake_pixels[i][0] = target_x
                    snake_pixels[i][1] = target_y
                else:
                    # 否则进行插值移动
                    move_x = dx * pixels_per_frame / distance
                    move_y = dy * pixels_per_frame / distance
                    
                    snake_pixels[i][0] += move_x
                    snake_pixels[i][1] += move_y
                    
                    # 穿墙处理
                    if snake_pixels[i][0] < 0:
                        snake_pixels[i][0] += MAP_WIDTH
                    elif snake_pixels[i][0] >= MAP_WIDTH:
                        snake_pixels[i][0] -= MAP_WIDTH
                        
                    if snake_pixels[i][1] < 0:
                        snake_pixels[i][1] += MAP_HEIGHT
                    elif snake_pixels[i][1] >= MAP_HEIGHT:
                        snake_pixels[i][1] -= MAP_HEIGHT


def update_effects():
    """更新活动效果的状态"""
    global active_effects, speed, move_delay
    
    current_time = pygame.time.get_ticks()
    effects_to_remove = []
    
    # 检查所有活动效果
    for effect, end_time in active_effects.items():
        if current_time >= end_time:
            effects_to_remove.append(effect)
    
    # 移除过期的效果
    for effect in effects_to_remove:
        if effect == "speed" or effect == "slow":
            # 重置速度
            speed = 6  # 默认速度
            move_delay = 1000 / speed
        
        del active_effects[effect]


def change_speed(delta):
    global speed, move_delay
    speed = max(1, min(20, speed + delta))  # 限制速度在1-20之间
    move_delay = 1000 / speed


def change_theme(theme_index):
    global current_theme, theme_colors
    theme_keys = list(THEMES.keys())
    if 0 <= theme_index < len(theme_keys):
        current_theme = theme_keys[theme_index]
        theme_colors = get_theme_colors(current_theme)


running = True
while running:
    dt = clock.tick(FPS)  # 获取每帧的时间间隔(毫秒)

    # 事件处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # 左键点击
                if game_state == "menu":
                    # 在菜单界面处理点击
                    result = handle_menu_click(event.pos, menu_buttons)
                    if result == "start":
                        game_state = "game"
                        game_started = False  # 重置游戏状态
                        # 重置游戏数据
                        snake = [[5, 5], [4, 5], [3, 5]]
                        snake_pixels = []
                        for segment in snake:
                            snake_pixels.append([segment[0] * CELL_SIZE, segment[1] * CELL_SIZE])
                        direction = (1, 0)
                        next_direction = direction
                        food = [random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1)]
                        food_type = 0
                        score = 0
                        snake_length = 3
                        obstacles = []
                        obstacle_count = 0
                        items = []
                        active_effects = {}
                        start_time = time.time()
                        total_pause_time = 0
                        last_elapsed_time = 0
                    elif result == "rules":
                        game_state = "rules"
                        scroll_offset = 0
                    elif result == "exit":
                        game_state = "exit_confirm"
                elif game_state == "rules":
                    # 在规则界面处理点击
                    back_button, content_height, content_area_height = draw_rules_screen(screen, WIDTH, HEIGHT, scroll_offset)
                    if back_button.collidepoint(event.pos):
                        # 如果是从游戏内菜单进入的规则界面，返回到游戏内菜单
                        if from_game_menu:
                            game_state = "game_menu"
                            from_game_menu = False  # 重置标记
                        else:
                            game_state = "menu"
                        scroll_offset = 0
                    else:
                        # 检查是否点击了滚动条
                        scrollbar_width = 12
                        scrollbar_x = WIDTH - 40
                        scrollbar_y = 120
                        content_area_height = HEIGHT - 180
                        
                        if content_height > content_area_height:
                            scrollbar_rect = pygame.Rect(scrollbar_x, scrollbar_y, scrollbar_width, content_area_height)
                            if scrollbar_rect.collidepoint(event.pos):
                                dragging_scrollbar = True
                                scroll_ratio = (event.pos[1] - scrollbar_y) / content_area_height
                                scroll_ratio = max(0, min(1, scroll_ratio))
                                scroll_offset = int(scroll_ratio * max(0, content_height - content_area_height))
                elif game_state == "exit_confirm":
                    # 在退出确认界面处理点击
                    yes_button, no_button = draw_exit_confirm_dialog(screen, WIDTH, HEIGHT)
                    if yes_button.collidepoint(event.pos):
                        running = False
                    elif no_button.collidepoint(event.pos):
                        game_state = "menu"
                elif game_state == "game_menu":
                    # 在游戏内菜单处理点击
                    # 获取按钮位置（不需要重新绘制）
                    continue_button = pygame.Rect((WIDTH - 320) // 2 + (320 - 220) // 2, 
                                                 (HEIGHT - 320) // 2 + 100, 220, 50)
                    rules_button = pygame.Rect((WIDTH - 320) // 2 + (320 - 220) // 2, 
                                              (HEIGHT - 320) // 2 + 100 + 50 + 25, 220, 50)
                    exit_button = pygame.Rect((WIDTH - 320) // 2 + (320 - 220) // 2, 
                                             (HEIGHT - 320) // 2 + 100 + 2 * (50 + 25), 220, 50)
                    
                    if continue_button.collidepoint(event.pos):
                        game_state = "game"
                    elif rules_button.collidepoint(event.pos):
                        game_state = "rules"
                        scroll_offset = 0
                        from_game_menu = True  # 标记从游戏内菜单进入
                    elif exit_button.collidepoint(event.pos):
                        game_state = "game_exit_confirm"
                elif game_state == "game_exit_confirm":
                    # 在游戏内退出确认界面处理点击
                    # 获取按钮位置（不需要重新绘制）
                    dialog_x = (WIDTH - 400) // 2
                    dialog_y = (HEIGHT - 200) // 2
                    yes_button = pygame.Rect(dialog_x + 400 // 2 - 100 - 15, 
                                           dialog_y + 200 - 70, 100, 40)
                    no_button = pygame.Rect(dialog_x + 400 // 2 + 15, 
                                          dialog_y + 200 - 70, 100, 40)
                    
                    if yes_button.collidepoint(event.pos):
                        # 返回到初始化菜单
                        game_state = "menu"
                        # 重置游戏状态
                        game_started = False
                        from_game_menu = False
                        # 重置游戏数据
                        snake = [[5, 5], [4, 5], [3, 5]]
                        snake_pixels = []
                        for segment in snake:
                            snake_pixels.append([segment[0] * CELL_SIZE, segment[1] * CELL_SIZE])
                        direction = (1, 0)
                        next_direction = direction
                        food = [random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1)]
                        food_type = 0
                        score = 0
                        snake_length = 3
                        obstacles = []
                        obstacle_count = 0
                        items = []
                        active_effects = {}
                        start_time = time.time()
                        total_pause_time = 0
                        last_elapsed_time = 0
                    elif no_button.collidepoint(event.pos):
                        game_state = "game_menu"
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                dragging_scrollbar = False
        elif event.type == pygame.MOUSEWHEEL and game_state == "rules":
            # 在规则界面处理滚轮事件
            scroll_offset -= event.y * 30
            scroll_offset = max(0, min(scroll_offset, max(0, content_height - content_area_height)))
        elif event.type == pygame.MOUSEMOTION:
            if game_state == "rules" and dragging_scrollbar:
                # 拖拽滚动条
                scrollbar_width = 12
                scrollbar_x = WIDTH - 40
                scrollbar_y = 120
                content_area_height = HEIGHT - 180
                
                if content_height > content_area_height:
                    mouse_y = event.pos[1]
                    scroll_ratio = (mouse_y - scrollbar_y) / content_area_height
                    scroll_ratio = max(0, min(1, scroll_ratio))
                    scroll_offset = int(scroll_ratio * max(0, content_height - content_area_height))
            elif game_state == "game_menu":
                # 游戏内菜单状态下的鼠标移动，不需要重复绘制，避免闪烁
                # 按钮悬停效果会在主循环的重绘部分处理
                pass
            elif game_state == "game_exit_confirm":
                # 游戏内退出确认状态下的鼠标移动，不需要重复绘制，避免闪烁
                # 按钮悬停效果会在主循环的重绘部分处理
                pass
        elif event.type == pygame.KEYDOWN and game_state == "game":
            # 只在游戏状态下处理键盘事件
            # 记录下一个方向，防止反向
            new_dir = None
            # 检查是否是有效的方向键
            valid_key_pressed = False
            
            if event.key == pygame.K_UP and direction != (0, 1):
                new_dir = (0, -1)
                valid_key_pressed = True
            elif event.key == pygame.K_DOWN and direction != (0, -1):
                new_dir = (0, 1)
                valid_key_pressed = True
            elif event.key == pygame.K_LEFT and direction != (1, 0):
                new_dir = (-1, 0)
                valid_key_pressed = True
            elif event.key == pygame.K_RIGHT and direction != (-1, 0):
                new_dir = (1, 0)
                valid_key_pressed = True
            
            # 处理有效方向键
            if valid_key_pressed and new_dir:
                # 将方向加入队列
                if len(key_queue) < 3:  # 限制队列长度
                    if not key_queue or key_queue[-1] != new_dir:  # 避免重复添加相同方向
                        key_queue.append(new_dir)
            
            # 速度控制
            elif event.key == pygame.K_PLUS or event.key == pygame.K_EQUALS:
                change_speed(1)
            elif event.key == pygame.K_MINUS:
                change_speed(-1)
            # 暂停控制
            elif event.key == pygame.K_SPACE:
                if not game_started:
                    game_started = True
                    start_time = time.time() # Reset start time when game starts
                    if sounds_loaded:
                        pygame.mixer.Sound.play(start_sound)
                elif not paused:
                    paused = True
                    pause_start_time = time.time()
                else:
                    paused = False
                    if pause_start_time is not None:
                        total_pause_time += time.time() - pause_start_time
                        pause_start_time = None
            # 平滑动画开关
            elif event.key == pygame.K_a:
                smooth_animation = not smooth_animation
                # 如果关闭平滑动画，将所有像素位置重置为网格位置
                if not smooth_animation:
                    snake_pixels = []
                    for segment in snake:
                        snake_pixels.append([segment[0] * CELL_SIZE, segment[1] * CELL_SIZE])
            
            # 主题切换
            elif event.key in [pygame.K_1, pygame.K_2, pygame.K_3, pygame.K_4]:
                theme_index = event.key - pygame.K_1  # 将K_1映射到0，K_2映射到1，等等
                change_theme(theme_index)
            
            # ESC键打开游戏内菜单
            elif event.key == pygame.K_ESCAPE:
                game_state = "game_menu"

    # 更新游戏状态
    if game_state == "game" and game_started and not paused:
        # 更新活动效果
        update_effects()
        
        # 障碍物生成计时
        obstacle_timer += dt
        if obstacle_timer >= obstacle_interval:
            generate_obstacle()
            obstacle_timer = 0
        
        # 道具生成计时
        item_timer += dt
        if item_timer >= item_interval:
            generate_item()
            item_timer = 0

    # 更新蛇的像素位置（用于平滑动画）
    if game_state == "game" and smooth_animation and game_started:
        update_snake_pixels(dt)

    # 控制蛇移动的节奏
    if game_state == "game" and not paused and game_started:
        move_timer += dt
        if move_timer >= move_delay:
            move_snake()
            move_timer = 0

    # 重绘界面
    if game_state == "menu":
        menu_buttons = draw()
    elif game_state == "rules":
        back_button, content_height, content_area_height = draw()
    elif game_state == "exit_confirm":
        yes_button, no_button = draw()
    elif game_state == "game_menu":
        # 先绘制游戏界面作为背景
        draw_game()
        # 然后绘制游戏内菜单弹窗
        continue_button, rules_button, exit_button = draw_game_menu(screen, WIDTH, HEIGHT)
    elif game_state == "game_exit_confirm":
        # 先绘制游戏界面作为背景
        draw_game()
        # 然后绘制游戏内退出确认对话框
        yes_button, no_button = draw_game_exit_confirm_dialog(screen, WIDTH, HEIGHT)
    elif game_state == "game":
        draw()
    
    pygame.display.flip()

pygame.quit()
sys.exit()
